package org.tis.tools.abf.module.jnl.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.beanutils.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.tis.tools.abf.module.ac.entity.*;
import org.tis.tools.abf.module.jnl.dao.EntryDataMapper;
import org.tis.tools.abf.module.jnl.exception.OperateLogException;
import org.tis.tools.abf.module.jnl.service.IEntryDataService;
import org.tis.tools.abf.module.om.entity.*;
import org.tis.tools.abf.module.sys.entity.*;
import org.tis.tools.core.utils.StringUtil;
import org.tis.tools.model.log.LogData;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by chenchao
 * Created on 2018/10/29 20:07
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class EntryDataServiceImpl extends ServiceImpl<EntryDataMapper, LogData> implements IEntryDataService {


    /**
     * @param guid 操作数据记录的guid
     * @return 数据实体的对象
     * @throws OperateLogException 操作异常
     */
    @Override
    public Object getEntity(String guid,String className) throws NoSuchFieldException, IllegalAccessException {

        Object object = null;
        switch (className){
            case "AcApp":
                AcApp acApp = this.baseMapper.getAcApp(guid);
                object = getEntityData(acApp);
                break;
            case "AcAppConfig":
                AcAppConfig acAppConfig = this.baseMapper.getAcAppConfig(guid);
                object = getEntityData(acAppConfig);
                break;
            case "AcDatascope":
                AcDatascope acDatascope = this.baseMapper.getAcDatascope(guid);
                object = getEntityData(acDatascope);
                break;
            case "AcEntity":
                AcEntity acEntity = this.baseMapper.getAcEntity(guid);
                object = getEntityData(acEntity);
                break;
            case "AcEntityfield":
                AcEntityfield acEntityfield = this.baseMapper.getAcEntityfield(guid);
                object = getEntityData(acEntityfield);
                break;
            case "AcFunc":
                AcFunc acFunc = this.baseMapper.getAcFunc(guid);
                object = getEntityData(acFunc);
                break;
            case "AcFuncAttr":
                AcFuncAttr acFuncAttr = this.baseMapper.getAcFuncAttr(guid);
                object = getEntityData(acFuncAttr);
                break;
            case "AcMenu":
                AcMenu acMenu = this.baseMapper.getAcMenu(guid);
                object = getEntityData(acMenu);
                break;
            case "AcOperator":
                AcOperator acOperator = this.baseMapper.getAcOperator(guid);
                object = getEntityData(acOperator);
                break;
            case "AcOperatorConfig":
                AcOperatorConfig acOperatorConfig = this.baseMapper.getAcOperatorConfig(guid);
                object = getEntityData(acOperatorConfig);
                break;
            case "AcOperatorFunc":
                AcOperatorFunc acOperatorFunc = this.baseMapper.getAcOperatorFunc(guid);
                object = getEntityData(acOperatorFunc);
                break;
            case "AcOperatorIdentity":
                AcOperatorIdentity acOperatorIdentity = this.baseMapper.getAcOperatorIdentity(guid);
                object = getEntityData(acOperatorIdentity);
                break;
            case "AcOperatorIdentityres":
                AcOperatorIdentityres acOperatorIdentityres = this.baseMapper.getAcOperatorIdentityres(guid);
                object = getEntityData(acOperatorIdentityres);
                break;
            case "AcOperatorMenu":
                AcOperatorMenu acOperatorMenu = this.baseMapper.getAcOperatorMenu(guid);
                object = getEntityData(acOperatorMenu);
                break;
            case "AcOperatorRole":
                AcOperatorRole acOperatorRole = this.baseMapper.getAcOperatorRole(guid);
                object = getEntityData(acOperatorRole);
                break;
            case "AcOperatorShortcut":
                AcOperatorShortcut acOperatorShortcut = this.baseMapper.getAcOperatorShortcut(guid);
                object = getEntityData(acOperatorShortcut);
                break;
            case "AcRole":
                AcRole acRole = this.baseMapper.getAcRole(guid);
                object = getEntityData(acRole);
                break;
            case "AcRoleDatascope":
                AcRoleDatascope acRoleDatascope = this.baseMapper.getAcRoleDatascope(guid);
                object = getEntityData(acRoleDatascope);
                break;
            case "AcRoleEntity":
                AcRoleEntity acRoleEntity = this.baseMapper.getAcRoleEntity(guid);
                object = getEntityData(acRoleEntity);
                break;
            case "AcRoleEntityfield":
                AcRoleEntityfield acRoleEntityfield = this.baseMapper.getAcRoleEntityfield(guid);
                object = getEntityData(acRoleEntityfield);
                break;
            case "AcRoleFunc":
                AcRoleFunc acRoleFunc = this.baseMapper.getAcRoleFunc(guid);
                object = getEntityData(acRoleFunc);
                break;
            case "OmEmpGroup":
                OmEmpGroup omEmpGroup = this.baseMapper.getOmEmpGroup(guid);
                object = getEntityData(omEmpGroup);
                break;
            case "OmEmployee":
                OmEmployee omEmployee = this.baseMapper.getOmEmployee(guid);
                object = getEntityData(omEmployee);
                break;
            case "OmEmpOrg":
                OmEmpOrg omEmpOrg = this.baseMapper.getOmEmpOrg(guid);
                object = getEntityData(omEmpOrg);
                break;
            case "OmEmpPosition":
                OmEmpPosition omEmpPosition = this.baseMapper.getOmEmpPosition(guid);
                object = getEntityData(omEmpPosition);
                break;
            case "OmGroup":
                OmGroup omGroup = this.baseMapper.getOmGroup(guid);
                object = getEntityData(omGroup);
                break;
            case "OmGroupApp":
                OmGroupApp omGroupApp = this.baseMapper.getOmGroupApp(guid);
                object = getEntityData(omGroupApp);
                break;
            case "OmOrg":
                OmOrg omOrg = this.baseMapper.getOmOrg(guid);
                object = getEntityData(omOrg);
                break;
            case "OmPosition":
                OmPosition omPosition = this.baseMapper.getOmPosition(guid);
                object = getEntityData(omPosition);
                break;
            case "OmPositionApp":
                OmPositionApp omPositionApp = this.baseMapper.getOmPositionApp(guid);
                object = getEntityData(omPositionApp);
                break;
            case "SysChannelCtl":
                SysChannelCtl sysChannelCtl = this.baseMapper.getSysChannelCtl(guid);
                object = getEntityData(sysChannelCtl);
                break;
            case "SysDict":
                SysDict sysDict = this.baseMapper.getSysDict(guid);
                object = getEntityData(sysDict);
                break;
            case "SysDictItem":
                SysDictItem sysDictItem = this.baseMapper.getSysDictItem(guid);
                object = getEntityData(sysDictItem);
                break;
            case "SysDutyDef":
                SysDutyDef sysDutyDef = this.baseMapper.getSysDutyDef(guid);
                object = getEntityData(sysDutyDef);
                break;
            case "SysErrCode":
                SysErrCode sysErrCode = this.baseMapper.getSysErrCode(guid);
                object = getEntityData(sysErrCode);
                break;
            case "SysRunConfig":
                SysRunConfig sysRunConfig = this.baseMapper.getSysRunConfig(guid);
                object = getEntityData(sysRunConfig);
                break;
            case "SysSeqno":
                SysSeqno sysSeqno = this.baseMapper.getSysSeqno(guid);
                object = getEntityData(sysSeqno);
                break;
            default:break;
        }

        return object;
    }


    /**
     *  将类名转换为大写
     *  将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空，则返回空字符串。</br>
     *  例如：AcApp->ac_app
     *  @param className 转换前的类名字符串
     *  @return 转换后下划线大写类名的字符串
     */
    private String getParamName(String className){
        if (StringUtil.isEmpty(className)){
            return "";
        }

        StringBuilder result = new StringBuilder();
        //将NAME_ 拼接在最前面
        result.append("NAME_");
        // 将第一个字符处理成小写
        result.append(className.substring(0, 1).toUpperCase());
        // 循环处理其余字符
        for (int i = 1; i < className.length(); i++) {
            String s = className.substring(i, i+1);
            // 在大写字母前添加下划线
            if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                result.append("_");
            }
            // 其他字符直接转成小写
            result.append(s.toUpperCase());
        }
        return result.toString();
    }

    private Object getEntityData(Object object) throws NoSuchFieldException, IllegalAccessException {

        if (object == null) {
            return object;
        }

        Map<String, Object> map = new HashMap<>();
        BeanMap beanMap = new BeanMap(object);
        Iterator<String> it = beanMap.keyIterator();
        while (it.hasNext()) {
            String name = it.next();
            Object value = beanMap.get(name);


            //转换时会将类名也转换成属性，此处去掉
            if (value != null && !name.equals("class")) {
                //如果数据类型为时间时,转换为时间格式
                String classType = object.getClass().getDeclaredField(name).getType().getName();
                int lastIndex = classType.lastIndexOf(".");
                classType = classType.substring(lastIndex + 1);
                if ("Date".equals(classType)){
                    if (StringUtil.isNotEmpty(value.toString())){
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
                        //如果时间为
                        if ("00:00:00".equals(value.toString().substring(11,19))){
                            simpleDateFormat.applyPattern("yyyy-MM-dd");
                        }else {
                            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");
                        }
                       value = simpleDateFormat.format(new Date(value.toString()));
                    }
                }

                map.put(object.getClass().getField(getParamName(name)).get(null).toString(),value);
            }
        }
    return map;
    }
//
//  现在没有使用到的方法
//    public static Object getValue(String fieldName,Class<?> clazz)throws Exception{
//                Field[] fields = clazz.getDeclaredFields();
//                for(Field field:fields){
//                        String name = field.getName();
//                       if(fieldName.equals(name)){
//                                return field.get(clazz);
//                           }
//                    }
//                return null;
//            }
}
